package logo.utils;

import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;

@SuppressWarnings("serial")
public class TurtleDisplay extends JPanel {
    /** Object for displaying lines drawn by a Logo Turtle **/

    /**
       Virtual coordinates of extreme points of the display
	Coordinates are in the range [-100,100].
    **/

    double left = -200F;
    double bottom = -200F;
    double right = 200F;
    double top = 200F;
    
    double xscale, yscale;	// scale factors to convert coords to pixels
    int ymax;			// max pixel y coordinate

    /** xscale, yscale, ymax must be updated automatically if the window
	is resized **/
    /* need to catch an AWTEvent (ComponentEvent) to resize them properly */

    Container myContainer;	// container for this display

    Color foregroundColour;

    Image myImage;		// off-screen contents of this display
    Image turtleImage;		// current image of turtle

    Shape turtleShape;
    AffineTransform turtleXform;
    final int TURTLE_WIDTH = 8;
    final int TURTLE_HEIGHT = 8;

    public TurtleDisplay(int width, int height){
	/** Create a new TurtleDisplay object with given width
	    and height **/
	this (makeDefaultFrame(width, height));
    }

    public TurtleDisplay(Container cntnr){
	/** Create a new TurtleDisplay object with given width
	    and height **/
	super();
	//setSize(width, height);
	
	myContainer = cntnr;
	//myContainer.add(this);
	//myContainer.validate();
	//myContainer.setVisible(true);
	setVisible(true);
	//gc = getGraphics();
	//Dimension dim = getSize();

	//System.out.println("Width is " + dim.width + " Height is " + dim.height);
	init(TURTLE_WIDTH, TURTLE_HEIGHT);
	setForeground(0, 200, 0);
	//setBackground(10, 10, 10);	
	setBackground(Color.yellow);
	//showTurtle(0, 0);
    }

    /** Create a turtle of the given dimensions */
    public void init(int width, int height)
    {
	//setIcon(new ImageIcon(myImage));

	/* Use a triangle as default turtle */
	int[] xs = {0, width/2, width};
	int[] ys = {0, height, 0};
	turtleShape = new Polygon(xs, ys, 3);
    }

    public Image makeTurtleImg(Shape turtleShape, int width, int height) {
	Image result = createImage(width, height);
	if (result == null) {
	    System.out.println("Failed to create turtle");
	    return result;
	}
	Graphics2D g2 = (Graphics2D)result.getGraphics();
	g2.setColor(Color.white);
	// should probably make background transparent
	g2.draw(turtleShape);
	return result;
    }
    
    public static Frame makeDefaultFrame(int width, int height) {
	Frame result = new Frame();
	result.setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR));
	result.setSize(width, height);
	result.setBackground(Color.cyan);

	return result;
    }

    /** Show the turtle at the specified coordinates with the given bearing. */
    public void showTurtle(double bearing, double x, double y) {
	int tx = convertX(x);
	int ty = convertY(y);
	turtleXform = AffineTransform.getTranslateInstance(tx, ty);
	turtleXform.rotate(bearing,
			   turtleImage.getWidth(this)/2,
			   turtleImage.getHeight(this)/2);
			   
	//getGraphics().drawImage(myImage, 0, 0, this);
    }

    /** Do not show the turtle. */
    public void hideTurtle() {
	turtleXform = null;
    }

    public void setSize(int width, int height)
    {
	super.setSize(width, height);
	// should probably copy from old image
	xscale = (width - 1)/(right - left);
	yscale = (height - 1)/(top - bottom);
	ymax = height - 1;
	setVisible(true);
	myImage = createImage(width, height);
	turtleImage = makeTurtleImg(turtleShape,
				    TURTLE_WIDTH,
				    TURTLE_HEIGHT);
    }

    public void paintComponent(Graphics g) {
	super.paintComponent(g);
	Graphics2D g2 = (Graphics2D) g;
	//g2.setColor(Color.green);
	if (myImage != null)
	    g2.drawImage(myImage, 0, 0, this);
	if ((turtleImage != null) && (turtleXform != null))
	    g2.drawImage(turtleImage, turtleXform, this);
    }

    public void clear() {
	Dimension dims = getSize();
	myImage.getGraphics().clearRect(0,0, dims.width, dims.height);
	repaint();
    }
    
    protected int convertX(double x) {
	/** Convert the given x coordinate to pixel coordinate **/
	return (int)((x - left) * xscale);
    }

    protected int convertY(double y) {
	/** Convert the given y coordinate to pixel coordinate **/
	return (int)(ymax - ((y - bottom) * yscale));
    }
    
    protected void setCoordinateLimits(double minX, double minY,
				       double maxX, double maxY) {
	left = minX;
	bottom = minY;
	right = maxX;
	top = maxY;
	xscale = (getSize().width - 1)/(right - left);
	yscale = (getSize().height - 1)/(top - bottom);
    }

    public void setForeground(int r, int g, int b) {
	Color c = new Color(r,g,b);
	foregroundColour = c;
    }

    public void setBackground(int r, int g, int b) {
	Color c = new Color(r, g, b);
	/*
	((Graphics2D) myImage.getGraphics()).setColor(c);
	*/
	setBackground(c);
    }

    public void drawSegment(double x,double y , double x1, double y1) {
	int startX = convertX(x);
	int startY = convertY(y);
	int endX = convertX(x1);
	int endY = convertY(y1);

	Graphics2D g2 = (Graphics2D) myImage.getGraphics();
	g2.setColor(foregroundColour);
	g2.drawLine(startX, startY, endX, endY);
	repaint();
    }

}
